package com.acme.bankapp.domain.bank;

import java.io.*;
import java.util.*;

import com.acme.bankapp.domain.exception.*;
import com.acme.bankapp.service.listener.*;

/**
 * Class stores clients and listeners
 * @author alex
 */
@SuppressWarnings("serial")
public class Bank implements Serializable {
	private Set<Client> clients;
	private List<ClientRegistrationListener> listeners;
	
	/**
	 * The default constructor
	 */
	public Bank() {
		this.clients = new HashSet<Client>();
		this.listeners = new LinkedList<ClientRegistrationListener>();
		this.listeners.add(new ClientRegistrationListener() {
			public void onClientAdded(Client client) {
				System.out.println("* " + client.getName() + " " + new Date());
			}
		});
	}
	
	/**
	 * @param client the client
	 * @return the client
	 */
	public Client getClient(Client client) {
		for (Client bankClient : this.clients) {
			if (bankClient.equals(client))
				return bankClient;
		}
		return null;
	}
	
	/**
	 * @param client the client
	 * @throws ClientExistsException 
	 */
	public void addClient(Client client) throws ClientExistsException {
		if (!this.clients.contains(client)) {
			this.clients.add(client);
			this.runListeners(client);
		} else {
			throw new ClientExistsException();
		}
	}
	
	/**
	 * @return the clients
	 */
	public Set<Client> getClients() {
		Set<Client> immutable = new HashSet<Client>();
		for (Client client : this.clients) {
			try {
				immutable.add((Client) client.clone());
			} catch (CloneNotSupportedException e) {
				System.out.println("Err: Clone not supported!");
			}
		}
		return immutable;
	}
	
	/**
	 * @return the clients count
	 */
	public int getClientsCount() {
		return this.clients.size();
	}
	
	/**
	 * @param listener the listener
	 */
	public void addListener(ClientRegistrationListener listener) {
		this.listeners.add(listener);
	}
	
	/**
	 * @param client the client
	 */
	public void runListeners(Client client) {
		for (ClientRegistrationListener listener : this.listeners) {
			listener.onClientAdded(client);
		}
	}
}
